package com.sz.dao.frame;

import com.sz.bean.Page;
import com.sz.pojo.frame.BaseObject;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.Map;

/**
 * 所有的Dao的父类
 * @author 哈尼玛
 * @框架文件 所有Dao需要继承该类
 * @param <T> 
 */

@SuppressWarnings("unchecked")
public class BaseDao<T extends BaseObject<T>> {

    @Autowired
    private SessionFactory sessionFactory;


    /**
     * 获取和当前线程绑定的 Session
     * 
     * @return
     */
    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * 根据ID获取当前类的对象
     * 
     * @return
     */
    public T get(Class<T> type, Long id) {
        return getSession().get(type, id);
    }

    /**
     * 根据id获取当前对象
     * 
     * @param type 对象的class类
     * @param id 要加载对象的id
     * @return
     */
    public T load(Class<T> type, Long id) {
        return getSession().load(type, id);
    }

    /**
     * 根据条件获取list
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return
     */
    public List<T> find4Params(final String hql, final Map<String, Object> params) {
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.list();
    }

    public List<T> find4ParamsIn(final String hql, final Map<String, Object> params,Map<String,Long[]> params2){
    	 Query query = getSession().createQuery(hql);
         query.setCacheable(true);
         if (params != null && params.size() > 0) {
             for (String key : params.keySet()) {
                 query.setParameter(key, params.get(key));
             }
         }
         if(params2 != null && params2.size() > 0){
        	 for (String key : params2.keySet()) {
                 query.setParameterList(key, params2.get(key));
             }
         }
         return query.list();
    }
    
    /**
     * 根据条件获取list
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return list的第一个 T
     */
    public T find4ParamsUnique(final String hql, final Map<String, Object> params) {
        List<T> list = find4Params(hql, params);
        if (list != null && list.size() > 0) {
            return list.get(0);
        } else {
            return null;
        }
    }

    /**
     * 根据条件获取list并分页显示
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return
     */
    public List<T> find4Page(final String hql, final Map<String, Object> params, final Page page) {
        page.setRowTotal(countObject(hql, params));
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        query.setFirstResult(page.getFirstRow());
        query.setMaxResults(page.getPageSize());
        return query.list();
    }

    /**
     * 根据条件获取list并分页显示
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return
     */
    public List<T> find4Page(final String hql, final Map<String, Object> params, final Page page, final String idStr) {
        page.setRowTotal(countObject(hql, params, idStr));
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        query.setFirstResult(page.getFirstRow());
        query.setMaxResults(page.getPageSize());
        return query.list();
    }

    /**
     * 获取结果数量
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @param idStr(统计数量时查询的id的对应字符串，默认是id，如果对象定义了新的名字[如：user]则需要传入[user.id])
     * @return
     */
    public Integer countObject(final String hql, final Map<String, Object> params, final String idStr) {
        String hqlCount;
        if (null != idStr && idStr.trim().length() > 0) {
            hqlCount = "select count(" + idStr + ") " + hql.substring(hql.indexOf("from"));
        } else {
            hqlCount = "select count(*) " + hql.substring(hql.indexOf("from"));
        }
        List<Object> result = find4HQLUnique(hqlCount, params);
        if(result != null && result.size() > 0){
            Long count = (Long) result.get(0);
            return count.intValue();
        }
        return 0;
    }

    /**
     * 获取结果数量(没有对对象定义新名字时调用)
     * 
     * @param hql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return
     */
    public Integer countObject(final String hql, final Map<String, Object> params) {
        return countObject(hql, params, null);
    }

    /**
     * 根据条件获取list
     * 
     * @param entity(装载的实体类)
     * 
     * @param sql(以自定义变量的方式查询
     *            :name)
     * @param params（map形式，key是“name =”
     *            value是对应的查询条件）
     * @return
     */
    public List<T> find4SQL(final Class<?> entity, final String sql, final Map<String, Object> params) {
        SQLQuery query = getSession().createSQLQuery(sql);
        query.setCacheable(true);
        query.addEntity(entity);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.list();
    }

    /**
     * 根据条件获取list
     * 
     * @param hql(以自定义变量的方式查询 :name)
     * @param params（map形式，key是“name =” value是对应的查询条件）
     * @return List(Object [])
     */
    public List<Object[]> find4HQL(final String hql, final Map<String, Object> params) {
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.list();
    }
    
    /**
     * 根据条件获取list
     * 
     * @param hql(以自定义变量的方式查询 :name)
     * @param params（map形式，key是“name =” value是对应的查询条件）
     * @return List(Object)
     */
    public List<Object> find4HQLUnique(final String hql, final Map<String, Object> params) {
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.list();
    }

    /**
     * 保存
     * @param t
     */
    public void save(T t) {
        getSession().save(t);
        getSession().flush();
    }

    /**
     * 更新
     * @param t
     */
    public void update(T t) {
        getSession().update(t);
        getSession().flush();
    }

    /**
     * 删除
     * @param t
     */
    public void remove(T t) {
        getSession().delete(t);
        getSession().flush();
    }
    
    /**
     * 执行hql语句
     * @param hql
     * @param params
     * @return
     */
    public int query(final String hql, final Map<String, Object> params){
        Query query = getSession().createQuery(hql);
        query.setCacheable(true);
        if (params != null && params.size() > 0) {
            for (String key : params.keySet()) {
                query.setParameter(key, params.get(key));
            }
        }
        return query.executeUpdate();
    }
    
    /**
     * 执行sql语句
     * @param sql
     * @return
     */
    public int update4Sql(String sql){
        SQLQuery query = getSession().createSQLQuery(sql);
        return query.executeUpdate();
    }
    
}
